/*
* @Author: Administrator
* @Date:   2018-01-04 14:20:36
* @Last Modified by:   Administrator
* @Last Modified time: 2018-01-10 13:29:29
*/
const NativeModule = require('module')
const vm = require('vm')
const webpack = require('webpack')
const path = require('path')
const MemoryFs = require('memory-fs')
const serverConfig = require('../../webpack.server.config.js')
const serverWebpack = webpack(serverConfig)
const axios = require('axios')
const httpProxy = require('http-proxy-middleware')
const mfs = new MemoryFs()

const serverRender = require('../util/server_render')
serverWebpack.outputFileSystem = mfs
let bundle
serverWebpack.watch({}, (error, stats) => {
  if (error) { throw error } else {
    stats = stats.toJson()
    stats.errors.forEach(err => console.error(err))
    stats.warnings.forEach(warn => console.error(warn))
    const bundlePath = path.join(serverConfig.output.path, serverConfig.output.filename)
    bundle = mfs.readFileSync(bundlePath, 'utf-8')
  }
})
const getTemplate = () => {
  return new Promise((resolve, reject) => {
    axios.get('http://localhost:8084/dist/server_template.ejs')
      .then(res => resolve(res.data))
      .catch(reject)
  })
}
const getModuleFromString = (bundle, filename) => {
  const m = { exports: {} }
  const wrapper = NativeModule.wrap(bundle)
  const script = new vm.Script(wrapper, {
    filename: filename,
    displayErrors: true
  })
  const result = script.runInThisContext()
  result.call(m.exports, m.exports, require, m)
  return m
}

const serverDev = (app) => {
  app.use('/dist', httpProxy({
    target: 'http://localhost:8084'
  }))
  app.get('*', function (req, res, next) {
    if (!bundle) {
      res.send('等待编译')
    } else {
      getTemplate().then((template) => {
        const bundleModule = getModuleFromString(bundle, 'server_entry.js').exports
        serverRender(bundleModule, template, req, res).catch(next)
      }).catch(next)
    }
  })
}

module.exports = serverDev
